/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef TRI_TEMPLATE_SCENE_H_
#define TRI_TEMPLATE_SCENE_H_


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <fstream>

#include "entity.h" 
#include "glyph.h"
#include "shapes.h"
#include "base/logging.h"


namespace tri {

enum{
	TYPE_CUBE,
	TYPE_SPHERE,
	TYPE_GLYPH
};

enum{
	HEADER_CHUNK = 1200,
	CAMERA_CHUNK = 1300,
	ENTITY_LIST_CHUNK = 1400,
	ENTITY_CHUNK = 1410,
	MATERIAL_CHUNK = 1500,
	
	END_CHUNK = 10000
};

class EntityContainer{
public:
	EntityContainer(std::string id,int type,tri::entity* entity);
	virtual ~EntityContainer();
	
	int mType;
	tri::entity* mEntity;
	std::string mID;
};

class TemplateScene :  public tri::scene , public sigslot::has_slots<sigslot::multi_threaded_local> {
public:
	//constructors ans destructors
	TemplateScene(bool demo = false);
	virtual ~TemplateScene();
	
	//virtual methods
	virtual void on_scene_open();
	virtual void on_scene_close();
	virtual void on_screen_resize(int w,int h);
	
	//public methods
	void setResetOnSceneEntry(bool b);
	void setDynamicAspectRatio(bool b);
	
	void exportToCPP(std::string file);
	void exportAttributes(std::fstream& file_op);
	void exportNodes(std::fstream& file_op);
	void exportEntityAttributes(std::fstream& file_op);
	
	static std::string enumToStringType(int type);
	static int stringToEnumType(std::string type);
	static void save(TemplateScene*,std::string);
	static TemplateScene* load(std::string file);
	
	
	static void _save(TemplateScene*,std::string);
	static TemplateScene* _load(std::string file);
	static void writeHeaderChunk(std::fstream&,TemplateScene*);
	static void writeCameraChunk(std::fstream&,TemplateScene*);
	static void writeEndChunk(std::fstream&,TemplateScene*);
	static void writeEntityChunk(std::fstream&,TemplateScene*);
	static void writeMaterialChunk(std::fstream&,TemplateScene* scene);
	
	static void writeString(std::fstream&,std::string);
	static std::string readString(std::fstream&);
	static void writeInt(std::fstream&,int);
	static int readInt(std::fstream&);
	static void writeFloat(std::fstream&,float);
	static float readFloat(std::fstream&);
	static void writeVector(std::fstream&, tri::vector);
	static tri::vector readVector(std::fstream&);
	static void writeColor(std::fstream&, tri::graphics::RGBA);
	static tri::graphics::RGBA readColor(std::fstream&);
	
	void entitySelected(tri::events::event_entity* ent);
	
	std::string getQualifiedName(std::string type,std::string name);
	void addNewEntity(int type,std::string name);
	void connectEntity(std::string parent,std::string child);
	bool entityExists(std::string ent);
	void setEditEntity(std::string name);
	EntityContainer* getEditEntity();
	EntityContainer* getContainer(tri::entity* ent);
	EntityContainer* getContainer(std::string ent);
	void getEntityList(std::vector<std::string> &list);
	
	void addMaterial(std::string mat,bool override = false);
	void deleteMaterial(std::string);
	bool hasMaterial(std::string);
	void getMaterialList(std::vector<std::string>&);

	//static methods
	void setExportDirectory(std::string dir);
	void setSaveLoadDirectory(std::string dir);
	void setLoadImageDirectory(std::string dir);
	std::string getLoadImageDirectory();
	
	sigslot::signal0<sigslot::multi_threaded_local> EDIT_ENTITY_CHANGED;
	sigslot::signal0<sigslot::multi_threaded_local> MATERIAL_LIST_CHANGED;
	
private:
	//static attributes
	std::string mExportSceneDirectory;
	std::string mSaveLoadSceneDirectory;
	std::string mLoadImageDirectory;
	
	//private attributes
	std::map<std::string,EntityContainer*> mEntityMap;
	std::map<std::string,std::string> mMaterialMap;
	EntityContainer* mEditEntity;
	bool mResetOnSceneEntry;
	bool mDynamicAspectRatio;
	bool mHasInit;
	bool mDemo;
	
	//void dAddEntity(std::string type,std::string name);
};

}

#endif
